package jsmile.utils;

import au.com.bytecode.opencsv.CSVReader;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;

/**
 * Converts CSV data to format required by SMILE.
 *
 * @author ik
 */
public class CsvToSmileData {

    static class CmdArgs {

        @Parameter(names = {"-i", "--input"}, description = "Input CSV file.")
        String inputCsvFilename;
        @Parameter(names = {"-o", "--output"}, description = "Output SMILE data file for DBN.")
        String outputSmileDataFilename;
        @Parameter(names = {"-s", "--separator"}, description = "Separator in the input file. Default is tabulator.")
        Character separator = '\t';
        @Parameter(names = {"-h", "--help"}, help = true)
        boolean help = false;
    }

    public static String dbnNodeId(String nodeName, int t) {
        if (t > 0) {
            return nodeName + "_" + t;
        } else {
            return nodeName;
        }
    }

    public static void convert(String inputCsvFilename, String outputSmileDataFilename, Character separator) throws FileNotFoundException, IOException {
        convert(new FileReader(inputCsvFilename), outputSmileDataFilename, separator);
    }

    public static void convert(Reader inputCsvReader, String outputSmileDataFilename) throws IOException {
        convert(inputCsvReader, outputSmileDataFilename, '\t');
    }

    public static void convert(Reader inputCsvReader, String outputSmileDataFilename, Character separator) throws IOException {
        CSVReader reader = new CSVReader(inputCsvReader, separator);
        String[] header = reader.readNext();

        List<List<String[]>> batches = new ArrayList<>();
        List<String[]> batch = new ArrayList<>();
        int lastBatch = 1;
        for (String[] line : reader.readAll()) {
            int currentBatch = Integer.parseInt(line[0]);
            if (currentBatch != lastBatch) {
                // new batch was started
                batches.add(batch);
                batch = new ArrayList<>();
                lastBatch = currentBatch;
            }

            // put all values into list
            batch.add(Arrays.copyOfRange(line, 2, line.length));
        }
        batches.add(batch);
        reader.close();

        // print it into a new file
        PrintStream out = new PrintStream(outputSmileDataFilename);

        // print header
        String[] nodeNames = Arrays.copyOfRange(header, 2, header.length);
        String[] vals = new String[batches.get(0).size() * nodeNames.length];
        for (int i = 0; i < batches.get(0).size(); i++) {
            for (int j = 0; j < nodeNames.length; j++) {
                vals[(i * nodeNames.length) + j] = dbnNodeId(nodeNames[j], i);
            }
        }
        out.println(StringUtils.join(vals, ' '));

        // print content of each batch
        for (List<String[]> batch2 : batches) {
            int i = 0;
            for (String[] line : batch2) {
                for (String nodeValue : line) {
                    vals[i++] = nodeValue;
                }
            }
            out.println(StringUtils.join(vals, ' '));
        }
        out.close();

    }

    //public static void convert(List<String[]> batch, String outputSmileDataFilename, Character separator) {
    //}
    public static void main(String[] args) throws FileNotFoundException, IOException {
        // cmd line parsing
        CmdArgs params = new CmdArgs();
        new JCommander(params, args);
        convert(params.inputCsvFilename, params.outputSmileDataFilename, params.separator);
    }
}
